package com.cskaoyan.javase.array._6callby;

import java.util.Arrays;
import java.util.TooManyListenersException;

/**
 * 方法的传值问题
 * 何为方法的传参问题？
 *      指的是研究当一个实参，传入方法后，方法能否对这个实参做出修改？能够做出什么修改？
 * 这里要分为两个角度查看：
 *      1.基本数据类型实参
 *      2.引用数据类型实参
 * 在计算机当中，有两种传值的方式：
 *      1.值传递(call by value),指的是方法接收的不是实参本身,而是实参一个拷贝
 *          这样: 方法是不能对实参做出修改的
 *      2.引用传递(call by reference) ,指的是方法接收就是实参本身(实参的地址),不是拷贝
 *          这样: 方法是可以对实参做出修改
 *
 * 我们通过代码测试,要验证Java究竟是值传递还是引用传递:
 *      1.通过将一个int类型实参,变为2倍的方法,发现方法不能修改int类型实参的取值
 *          这说明,至少对于Java的基本数据类型实参,Java是值传递的
 *      2.通过将一个数组中的元素变为原先2倍的方法,发现方法可以修改引用数据类型元素的取值
 *          于是这说明,至少对于Java的引用数据类型实参,Java是引用传递的
 *
 *     以上,是大错特错的结论,是典型的中文互联网博客博主互相copy得出的结论.
 *
 *
 *     实际上Java只有值传递,Java在任何情况下,都不存在引用传递!
 *     值传递的结论:
 *          由于方法仅会得到实参的一个拷贝
 *          所以:
 *              1.实参是局部变量,那么方法不能对另外一个方法中的局部变量做任何修改
 *              这个局部变量包括: 基本数据类型变量和引用数据类型的引用
 *              实际上,Java肯定不可能存在引用传递,一旦有引用传递,局部变量就会在方法外部生效(局部变量就不"局部"了)
 *
 *              2.方法可以通过获取引用数据类型引用的拷贝,进而去访问原先引用所指向的对象
 *              那么就可以修改对象中元素的取值(称之为修改对象的状态)
 *
 * @since 16:06
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*int num = 10;
        doubleIntValue(num);
        // 10
        System.out.println(num);

        System.out.println("---------------");
        int[] arr = {1, 2, 3};
        doubleArrEle(arr);
        System.out.println(Arrays.toString(arr));*/

        int[] arr1 = {666, 777, 888};
        int[] arr2 = {111, 222, 333};
        System.out.println("交换引用之前的arr1:" + Arrays.toString(arr1));
        System.out.println("交换引用之前的arr2:" + Arrays.toString(arr2));
        /*
            如果能够交换成功,说明方法把数组引用本身就得到了,说明Java是引用传递的
            但如果交换失败,说明方法交换的是数组引用的拷贝,说明Java是值传递
         */
        swapArrReference(arr1, arr2);
        System.out.println("交换引用之后的arr1:" + Arrays.toString(arr1));
        System.out.println("交换引用之后的arr2:" + Arrays.toString(arr2));
    }

    public static void doubleIntValue(int num) {
        num *= 2;
        System.out.println("方法内部的num = " + num);
    }

    public static void doubleArrEle(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
    }

    // 需求,交换两个int类型数组的引用
    public static void swapArrReference(int[] arr1, int[] arr2) {
        int[] temp = arr1;
        arr1 = arr2;
        arr2 = temp;

        System.out.println("交换引用的方法中arr1:" + Arrays.toString(arr1));
        System.out.println("交换引用的方法中arr2:" + Arrays.toString(arr2));
    }
}
